#include "StompedReality/Core/IGame.h"
#include "StompedReality/Core/Input/InputSystem.h"
#include "StompedReality/Core/Input/Keys.h"
#include "StompedReality/Core/Logger.h"
#include "StompedReality/Core/OS/SystemMessageProcessor.h"
#ifdef LINUX
#include "StompedReality/Core/Input/linux/LinuxKeyboardHandler.h"
#elif WIN32
#include "StompedReality/Core/Input/Windows/WGLKeyboardHandler.h"
#include "StompedReality/Core/Input/Windows/WGLMouseHandler.h"
#endif // ifdef LINUX
#include <assert.h>
namespace StompedReality
{
namespace Input
{
InputSystem::InputSystem( ) :
  StompedReality::GameAccess( )
{
  this->m_Keyboard = new KeyboardInput( );
  this->m_KeyboardHandler = 0;
  this->m_Mouse = new MouseInput( );
  this->m_MouseHandler = 0;
}

InputSystem::~InputSystem( )
{
  LogCallFunctionInfo( "InputSystem", "Destructor" );

  delete this->m_Keyboard;
  delete this->m_KeyboardHandler;
  delete this->m_Mouse;
  delete this->m_MouseHandler;
}

void InputSystem::HandleInput( )
{
  if (this->m_KeyboardHandler)
    this->m_KeyboardHandler->UpdateKeys( );
  if (this->m_MouseHandler)
    this->m_MouseHandler->UpdateMouse( );

  /*
  if (this->IsKeyPressed(KEY_LEFT) || this->IsKeyUp(KEY_LEFT))
    std::cout << "key <- " << this->IsKeyDown(KEY_LEFT) << ", " << this->IsKeyPressed(KEY_LEFT) << ", " <<
         this->IsKeyUp(KEY_LEFT) << std::endl;
  */

/*  if (this->IsLeftButtonPressed() || this->IsLeftButtonUp())
   std::cout << "left " << this->IsLeftButtonDown() << ", " << this->IsLeftButtonPressed() << ", " <<
   this->IsLeftButtonUp() << std::endl;
  */

}

KeyboardHandler* InputSystem::GetKeyboardHandler( ) {
  return this->m_KeyboardHandler;
}

bool InputSystem::ParseConfig ( JsonPTR root )
{
  Json::Value rsRoot = root->get( "InputSystem", 0 );
  LogCallFunctionInfo( "InputSystem", "parseConfig" )
  LogInfoPair( "enable Keyboard", rsRoot.get ( "enableKeyboard", 0 ).asBool( ));
  LogInfoPair( "enable Mouse", rsRoot.get ( "enableMouse", 0 ).asBool( ));
  if ( rsRoot.get ( "enableKeyboard", 0 ).asBool( ) ) {
#ifdef LINUX
    this->m_KeyboardHandler = new LinuxKeyboardHandler( );
#elif WIN32
    this->m_KeyboardHandler = new WGLKeyboardHandler( );
#endif // ifdef LINUX
    assert ( this->m_Game != 0 );
    assert ( this->m_KeyboardHandler != 0 );
    assert ( this->m_Game->getSysMsgProcessor( ) != 0 );
    this->m_Game->getSysMsgProcessor( )->AddListener ( this->m_KeyboardHandler );

    assert( this->m_KeyboardHandler != 0 );
    if ( this->m_KeyboardHandler == 0 )
      return false;
    this->m_KeyboardHandler->SetKeyboard ( this->m_Keyboard );
    this->m_KeyboardHandler->Intialize( );
  }
  if ( rsRoot.get ( "enableMouse", 0 ).asBool( )) {
#ifdef LINUX
    this->m_KeyboardHandler = 0;
#elif WIN32
    this->m_MouseHandler = new WGLMouseHander( );
    assert ( this->m_Game != 0 );
    assert ( this->m_MouseHandler != 0 );
    assert ( this->m_Game->getSysMsgProcessor( ) != 0 );
    this->m_Game->getSysMsgProcessor( )->AddListener ( ( WGLMouseHander* ) this->m_MouseHandler );
#endif // ifdef LINUX
    assert( this->m_MouseHandler != 0 );
    if ( this->m_MouseHandler == 0 )
      return false;
    this->m_MouseHandler->SetMouse ( this->m_Mouse );
  }
  return true;
}

bool InputSystem::IsKeyDown ( const int key )
{
  return this->m_Keyboard->IsKeyDown ( key );
}

bool InputSystem::IsKeyPressed ( const int key )
{
  return this->m_Keyboard->IsKeyPressed ( key );
}

bool InputSystem::IsKeyUp ( const int key )
{
  return this->m_Keyboard->IsKeyUp ( key );
}

StompedReality::Math::Vector2 InputSystem::GetMousePosition( )
{
  return this->m_Mouse->GetPosition( );
}

StompedReality::Math::Vector2 InputSystem::GetMouseDelta( )
{
  return this->m_Mouse->GetPositionDelta( );
}

bool InputSystem::IsLeftButtonDown( )
{
  return this->m_Mouse->IsLeftButtonDown( );
}

bool InputSystem::IsLeftButtonPressed( )
{
  return this->m_Mouse->IsLeftButtonPressed( );
}

bool InputSystem::IsLeftButtonUp( )
{
  return this->m_Mouse->IsLeftButtonUp( );
}

bool InputSystem::IsRightButtonDown( )
{
  return this->m_Mouse->IsRightButtonDown( );
}

bool InputSystem::IsRightButtonPressed( )
{
  return this->m_Mouse->IsRightButtonPressed( );
}

bool InputSystem::IsRightButtonUp( )
{
  return this->m_Mouse->IsRightButtonUp( );
}

}
}
